MacSim is a Microcode simulator. The purpose of the MacSim application is the implementation of the example Microarchitecture presented on pages 126 - 134 in Structured Computer Organization, 2nd Edition, by Andrew S. Tanenbaum (from here on simply Tanenbaum).
The simulator wouldn╒t be of much use just by itself. Our goal was to produce an environment where the user could easily enter, change, and assemble a Microcode control store, and then execute that control store on a Macrocode image implemented by the Microcode.
The result of this desire to produce a Microcode development environment is MacSim. MacSim consists of 4 major parts all of which use or produce information necessary for one of the other parts. The 4 parts listed to the right .
The Text editor can be used to type in the source code for either Micro or Macro control stores. Although it╒s easiest to type your text into the MacSim editor we realize that it is limited in terms of a professional text editing environment. Most any Macintosh text editor can be used and MacSim will be able to read in the file.
The Microcode Assembler is an assembler for Microcode that follows the books Microcode syntax presented on page 146-147 in Tanenbaum. In addition we have added a Mnemonic Table which specifies the instruction set for the Macrocode Assembler to work with. The Microcode Assembler however expects both a Microcode and a Mnemonic╒s table before you can use it for the Macroassembler.
The Macrocode assembler is a simple table driven assembler that uses the Mnemonic table produced by the Microcode Assembler to assemble the program text and produce a Macrocode control store. The details of both the Micro and Macro Assemblers are covered later in this document.
The Simulator is the reason for MacSim╒s existence, all of the other parts are simply support allowing the students to enter and use information for the Simulator. The simulator is an exact implementation of the Microcode Architecture as presented in Tanenbaum with a few small changes to allow for I/O to and from the screen and keyboard.
System Requirements
MacSim will run on a Macintosh 512Ke, Macintosh Plus, Macintosh SE, Macintosh SE/30, Macintosh II, IIx, IIcx, IIci, and IIfx. It requires Apple System software version 6.0.2 or greater. MacSim will run on a Macintosh 512Ke but at least a Macintosh Plus with 1 megabyte of memory is recommended. A faster Macintosh is desirable if you are going to be running multiple simulations. A hard disk is nice, but not required.
Target Audience
Although it would be possible to use MacSim without Tanenbaum╒s book this document and the associated design document draw heavily on information presented by Tanenbaum. In many area╒s of this documents we refer to Tanenbaum╒s book because we find his explanations clear and concise and for us to reword them would either result in plagiarism or a loss of clarity. It is also assumed that the user is reasonably familiar with the Macintosh and it╒s operation. For additional information on using the Macintosh we suggest referencing the manuals that come with the Macintosh. The documentation provided by Apple is an excellent presentation of the use of the Macintosh desktop environment. MacSim follows most all of the Macintosh user interface guide lines and therefore should be rather simple to use.
In addition to basic Macintosh operation the reader is assumed to have some knowledge related to the use of Machine Language Assemblers. For us to provide a tutorial in the use of Assembler╒s is outside the scope of this document and the reader is encouraged to seek out appropriate documentation to be used in conjunction with this manual. Again Tanenbaum╒s book is an excellent companion to this reference manual and we STRONGLY encourage the reader to use this document and program in conjunction with a course using Tanenbaum╒s book.
Documentation Conventions
<KeyStroke> Any time you see this in the text it is to be read as a single key stroke. Such as <Return> or <Tab>.
Menu Title Text that is underlined is a title of a MacSim menu.
Menu Option Text that is italicized is a MacSim Menu Option.
Mouse Click Text that is a dotted underline is a Mouse operation.
Memory Location Sometimes the documentation will refer to a memory location by a symbolic name, rather than the actual memory address. When this is done the name will be in the style shown here.
Using MacSim
To the left is the MacSim Icon. To run MacSim all you need to do is find this Icon on the disk that came with this documentation and double-click on it with the Mouse. A double-click is a signal to the Macintosh that you would like to run a particular program and this action will start the program. If this is the first time that you have run MacSim then you will be presented with the a Window asking you for some information . At this time you should type in the requested information. To move between the different fields you can use the <tab> or the mouse. If you╒re not yet ready to type the information in you may click on the ╥Cancel╙ button. All of the fields must be filled out before the program will let you proceed. When you are done filling out the fields then you can press <Return>, <Enter>, or click in the ╥Ok╙ button.
After you have typed in the information, or you have done it before, then MacSim is ready to run.
Quick Tour of MacSim Menus
The Apple Menu
The Apple menu contains a list of your currently loaded desk accessories. In addition to the desk accessories there is also an option to find out About MacSim. If you choose this option you will see a Dialog describing MacSim and the version of MacSim. This documentation was written to go along with version 1.1 of MacSim. If there is a different version number in the About Box of your copy of MacSim then get a new copy of the Documentation.
The File Menu
The File menu allows you to do general file operations dealing with text files.
New creates a new text file. When you choose new you will be asked for the file type.
Open allows you to open an existing text file from the disk.
Close closes the front most window on the screen. Asking to save changes if necessary.
Delete allows you to delete a file without having to return to the Finder.
Save allows you to save the text into a file. If you choose this the first time then you will be prompted for a file name. After specifying a file name choosing save will not ask again.
Save As allows you to save to a specific file name, even if the window already has a name. This option prompts you for a file name every time.
Page Setup brings up the Pagesetup dialog for the currently selected printer allowing you to change the page orientation.
Print will print the contents of the front most window to the currently selected printer.
Quit option quits MacSim and closes all windows, asking to save changes if necessary.
The Edit Menu
The Edit Menu allows various operation on text files.
Undo is not supported by the MacSim editor. The option is there for desk accessories that do support Undo.
Cut copies the current text selection to the clipboard and then deletes the selection from the source file.
Copy copies the current text selection to the clipboard leaving the selection in the source file.
Paste replaces the current text selection with the contents of the clipboard.
Set Search allows you to set the text pattern for the find and replace options.
Find Text searches the text file for the text pattern as specified in Set Search. It searches from the current cursor location in the file to the bottom.
Replace Text replaces the current selection with the text pattern as specified in Set Search.
Goto Selection scrolls the window so that the current selection can be seen on the screen.
Change Window Type allows you to change the type of window to any one of the three basic text file types. For more details see the section of the text editor in this documentation.
Set Parent MicroCode allows you to set/change the parent Microcode of a Assembly text file. For more details see the section on Assembling in this documentation.
Options Menu
The Options menu allows you to control font and size of the text in the Text Editor window.
The Number of Fonts available is determined by the Fonts that you have installed in your system with the Font/DA Mover provided as part of the Apple System software.
Machine Menu
The Machine menu allows you to invoke various parts of the MacSim simulator.
Assemble will assemble the current window using either the Micro or Macro Assembler depending on the Window type as set when the file was created or with the Change Window Type option under the Edit menu. If the Assemble option is dimmed then that means the file is of type ╥Normal Text╙ and therefore can not be Assembled. Resetting the type with the Change Window Type command will make this option available.
Run Simulator is only available after you have successfully Assembled a Macrocode program. It is never highlighted for ╥Normal Text╙ or ╥Microcode Text╙. If you have an Assemble text window type forward and this option is not available try Assembling it, if it Assembles with no error you can then start a simulation of that program by choosing Run Simulator.
The MacSim Text Editor
The MacSim text editor is a basic editor and has almost no fancy functions. It follows Macintosh user interface guidelines, so anyone reasonably familiar with the Macintosh should be able to use it with no problems.
The window that the text appears in is a standard Macintosh window, complete with Close Box, Zoom Box, and Scroll Bars. All of these function in accordance with standard Macintosh user interface guidelines. There is one addition to the window. It is called the ╥Status Panel╙. The status Panel is a small box in the lower left hand corner of the screen that gives status information about the editor. Normally it will simply display the percent distance that the selection represents of the text. But after choosing a Menu option it will display the command that you just selected.
Find and Replace
One feature that is provided is a find/replace function. Find allows you to find a particular text pattern in the file. The find is done from the current insertion point down to the bottom of the document. When you have found a text pattern you may optionally replace the text with another text pattern. You can set both the find and replace text by choosing the Set Search option from the Edit menu.
File Type
The only part of MacSim that isn╒t like most editors is that each window has a file type. There are three possible types: No Type, Microcode, and Macrocode. The file types are stored separately from the text of the file so it will not affect the loading of text files into other text editors. Every time you choose New from the File menu you will be asked what type of file this is going to be .
If you don╒t know what kind of file it╒s going to be then No Type will suffice to start. A file of No Type can not be assembled however. MacSim uses the file type to determine which assembler to call when you choose the Assemble command from the Machine menu. If you want to change a file╒s type you may do so with the Change Window Type command under the Edit menu.
Editor Limitations
The editor does have some limitations. At this time it can not edit a text file over 32K in length. If you attempt to load a file that is longer than 32K you will be presented with a warning and only the first 32K will be loaded. This limit is not pleasant. But given the capabilities of the Tanenbaum architecture this limit seems very reasonable. The Tanenbaum Machine can only have 256 Microcode instructions, and only has 12 bit addressing. Given those two consideration 32K should be more than sufficient room for any source code that would need to be written.
MacSim should be able to load any file of type TEXT. Text files are generated by many word processor╒s and there are numerous text editors available on the market.
Microcode Assembler
Using the Microcode Assembler
The Microcode-assembler assembles and prepares a Microcode source program so that:
1. The Macro-assembler knows what symbols the Microcode implements, and
2. It sets up all the necessary data structures for the Simulator.
To use the Microcode-assembler you must have a text window of type Microcode as the front most window. If the window is not of type Microcode then you can choose the Change Window Type option from the Edit menu. If the window is of type Microcode and you wish to assemble it then you can choose Assemble from the Machine menu. If the assembly is successful then the Macintosh will simply return you to editing the file. If the Microcode source, or the Mnemonic table, has any errors then you will be notified with an error message, and most of the time the editor will select the section of text that caused the error. Additional information regarding the meaning and causes of most errors can be found later in this chapter.
If the assembly was successful and you intend on using this file as a Microcode parent then you must choose Save from the File menu so that MacSim has a chance to write the newly assembled information to disk. If you have successfully assembled a Microcode program and saved it to disk you can then go on to Assembling a Macrocode program in preparation for running a Simulation.
Microcode Assembler Syntax
The Microcode assembler syntax is similar to the one presented in Tanenbaum pg. 146-147 with the following exceptions.
Comments
Comments begin with a / character and end at the end of line.
Labels
All labels are alphanumeric and required to start with an alphabetic character, they are limited in length to the first 16 characters.
Conditional Jumps
The conditional jump syntax has been modified from if Condition then goto label to if Condition goto label. Where condition is the conditional flags presented in Tanenbaum╒s book.
Case Sensitive
The assembler is case sensitive and all reserved words (ie. alu,if .. goto, mbr, mar, a, b, etc,...) are required to be lower case. When referring to the -1 register no parentheses are required to surround it.
Binary Arithmetic
In all binary arithmetic operators the first operand is presumed to be the A bus and the second is the B bus.
Mnemonic Table Syntax
The Microcode is required to be followed by a Mnemonic table that describes the symbols used in the Macrocode assembly language. The mnemonic table is begun and ended with a single # character on a line by itself. Each mnemonic entry starts with the character-string mnemonic that is going to be used to reference that particular instruction. It is then followed by the opcode and a series of optional preset instruction labels and ended with a semi-colon.
The Mnemonic table to the left describes an instruction lodd that has an opcode of hex 0x4500.
The lower 4 bits, as indicated by the ╥-4╙ after the opcode, of the opcode are going to be used to store any operand that follows the Mnemonic in a Macrocode source. Any operand value following the lodd instruction will be masked to fit in these 4 bits. Therefore in our example you could represent values ranging from 0 to 15, anything larger would simply wrap around onto one of these 16 values.
Lodd also has two preset labels bx and cx whose scope is limited to the lodd instruction. These preset labels can be used in conjunction with the lodd instruction to create a higher level of abstraction for the Macrocode assembly language. For example you could enter the instruction:
lodd bx
This source code line would generate the opcode: 0x4503.
The mnemonic table additionally specifies an instruction retn that has an opcode of decimal 1024. The retn instruction takes no operands. This is identified by the absence of a + or - after the opcode. If a - is specified then the number of bits the operand will be encoded into is defined. If a + is specified then the operand value will be placed in the word immediately following the opcode. All numbers are presumed to be in decimal unless a 0x is placed in front of the number, then the number is treated as a hexadecimal number. There may be as many as 16 preset labels associated with each instruction.
Microcode Errors
If the Microcode assembler is unable to assemble the microcode it will return one of the following errors.
(1) Syntax error.
This error occurs when an illegal token is found or the token is misplaced. This occurs most often when a reserved word is misspelled or an illegal character is found in the text.
(2) Read or Write flags used multiple times.
This error occurs when the command rd or wr has been used more than once in a single line of Microcode.
(3 Illegal use of Jump field.
This error is returned when the goto field is used more than once in a line of Microcode.
(4) Multiple use of Shift field.
This error is returned when the shift field is used more than once in a line of Microcode.
(5) Inconsistent use of C bus.
This error occurs when more than one expression in the line of Microcode are storing the result in the C bus.
(6) Inconsistent use of B bus.
This error occurs when more than one expression uses the B bus for two different register values.
(7) Inconsistent use of A bus.
This error occurs when more than one expression uses the A bus for two different register values.
(8) Multiple use of ALU.
This error is returned when there is more than one use of the ALU in a single line of Microcode.
(9) Redefinition of Label.
You have used a label too many times. Get rid of it!!
(10) Improper use of reserved token ╘z╒.
(11) Improper use of reserved token ╘n╒.
Both of these errors are returned when the reserved token n or z are used someplace other than in the if n goto or if z goto format.
(12) Out of Microcode Controlstore address space.
You have exceeded the 256 word address space of the Microcode control store. You will have to shorten your Microcode so that it can fit in the controlstore memory.
Microcode Reserved Words
To the right is a list of Microcode Reserved words. These words can not be used as labels in the Microcode and therefore should be avoided. The words meaning are in accordance with the meaning presented in the book.
Macrocode Assembler
Using the Macro-Assembler
Using the Macro-assembler is similar to the Micro-assembler. The only difference is that the front most window needs to be of type Macrocode, as usual the window type can be changed with the Change Window Type command under the Edit menu. To assemble a Macrocode program you simply choose Assemble from the Machine menu. If there are no error╒s you are simply returned to editing the file, if there is an error during the assembly process you will be notified and the editor will try to select the offending line of code. After you have successfully assembled a Macrocode source you can then choose Run Simulator from the Machine menu and watch your program run. For more information on using the Simulator see the Simulation chapter in this document.
Microcode Parents
Each Macrocode window must have a Microcode parent associated with it. The Macro-assembler uses the parent file to retrieve the Mnemonic table and Microcode. Without a Microcode parent the Macro-assembler doesn╒t know what Mnemonics have been defined and therefore can not assemble your Macrocode source.
If you try to assemble a Macrocode program that has no Microcode parent you will be notified and asked to select a file to use as a Microcode parent. If you have already selected a Microcode parent and wish to change to another Microcode parent you may do so by choosing Set Parent Microcode from the Edit menu. Your choice of a Microcode parent is not saved with the Macrocode file. So if you close a Macrocode window, or quit the MacSim program, you will be asked to reselect a Microcode parent next time you wish to assemble a Macrocode file. The Microcode parent is remembered as long as the Macrocode window is open. MacSim will not ask you to reselect a parent file for that as long as a window is open.
Each open Macrocode window can have a different Microcode parent, or all the Macrocode windows could share the same Microcode parent. There is no restrictions on the selection of Microcode parent files. A single Microcode parent could have several children at any given time. Allowing the selection of different Microcode parents allows MacSim to actually run different versions of Microcode at the same time. Please see the chapter on the Simulator in this document for additional information.
Macrocode Assembler Syntax
The macrocode assembler has only a couple of pre-defined instructions.
Org is used to reset the location pointer during assembly. Org is followed by a number. This number describes the address of where the next Macrocode code should be assembled into in memory. Dw is used to allocate storage. It can preceded by a label that is useful for referencing it in later instructions. The initial value for the location follows the token dw.
For example contains a sample program that will fill two memory locations 34 and 35 with a 9 and 0 respectively. The label label1 will have the value 34 thus pointing to the defined storage space containing the value of 9.
In addition to the DW instruction there is another type of instruction for setting a constant. This is accomplish by having a label followed by an = character and then the number that will be assigned to it.
All other instructions in the Macrocode are defined in the Mnemonic table in the Microcode parent file. All instructions that have an operand specified in the Mnemonic table are required to be followed by a number or label.
PC Relative Addressing
If an operand is preceded by a % character it╒s value will be calculated relative to the current location pointer. This can be used for instructions that require PC relative offsets into the code.
Like the Microcode comments are begun by the / character and end at the end of line. The Macrocode assembler is case sensitive and requires that all reserved words be in lower case.
Macrocode Errors
There are several reasons for exiting the Macrocode assembler.
If a label is used but not defined the editor will select the unresolved reference after exiting.
The assembler will also exit if it does not recognize an instruction. This occurs most often when an instruction is mistyped.
Another possible exit condition is if the assembler finds an operand present, or missing, for an instruction that doesn╒t have, or requires, an operand. This can be verified in the Mnemonic table of the parent Microcode file.
If the location pointer goes above 4095 the Macrocode assembler will exit since this is all the memory the Simulator has for Macrocode instructions.
Macrocode Reserved Words
Since the Macrocode symbol list is determined by the mnemonic table given at the end of a particular Microcode the reserved word list is rather short. But there are two pre-defined assembler operations that need to be listed. They are:
org
dw
The Microcode Simulator
The MacSim Microcode Simulator is the reason for MacSim╒s existence. The editor and two assemblers exist to allow students to do development work and create, modify, and execute Microcode. The simulator is an exact implementation of the architecture as outlined on pages 126 - 134 of Tanenbaum╒s book. In addition to the basic CPU architecture presented, MacSim provides for simple I/O functions in order to provide a usable machine for the students to work with. Since Tanenbaum covers the Microcode Architecture in his book this section is dedicated to documenting the I/O subsystem and the memory map that MacSim uses.
Memory Map
The memory map is a simple mapping similar to some early 8-bit personal computers. It is much simpler than most of them, but none the less functional and it serves a purpose . We tried to keep the I/O model simple so that the student need not learn a complicated machine and is left free to concentrate on the Microcode.
The first location, zero, is required to contain the first Macrocode instruction to execute. Normally this will be a jump instruction to turn control over to the main part of the program. When the simulator starts the PC register is initialized to 0. Nothing says that the Microcode has to load an instruction from 0, but Tanenbaum╒s example architecture immediately starts a memory read at the address of the PC, which is zero to start with. If you want the Microcode to start executing instructions at some other initial point you will have to have the micro-code set the PC to the initial starting location and then load the first Macro-instruction from this newly calculated PC.
Location 0 First Instruction
Location 0 should contain the first Macrocode instruction to execute.
Location 1 InDev
Location 1 specifies the device id to receive input from. You select an input device by storing a pre-defined value into InDev. When the simulator sees a value in InDev it will start feeding the simulator any input it receives from that device. More information on how to actually accomplish I/O can be found in the section titled ╥General I/O Scheme╙.
Location 2 OutputCntl
Location 2 specifies the device id to direct output to. By selecting an output device the simulator can produce output on the screen, and send messages to other simulators currently executing.
Location 3 InputCntl
Location 3 specifies the current state of the input device. By polling and writing to InputCntl the simulator can read data from the currently selected input device.
Location 4 OutputCntl
Location 4 specifies the current state of the Output device. by polling and writing to OutputCntl the simulator can write data to the currently selected output device.
Location 5 & 6 InputCmnd & InputData
Locations 5 & 6 contain the result of an input operation. After completing the Input operation the simulator will leave the values of the input in InputCmnd & InputData. The meaning of the values depends on the type of device that you╒re receiving input from.
Locations 7 & 8 OutputCmnd & OutputData
By storing values into locations 7 & 8 and then storing the Initiate Output command in OutputCntl you can send data to a particular device. The meaning of OutputCmnd & OutputData depends on the type of device that the output is being directed to.
Locations 9-24 Reserved
Locations 9-24 are reserved for future MacSim enhancement.
Locations 25 - (4095 - Stack)
Location 25 on up to the top of stack pointer are available for user memory. The Microcode stack pointer is initialized to point to location 4095 and should grow down into memory.
Initial Microcode Environment
Each time you start a simulation the Microcode Architecture is initialized with certain values. This section is simply an enumeration of those values.
PC, AC, IR, TIR, A, B, C, D, E, F are set to Zero.
SP is set to $0FFF hex
AMask is set to $0FFF hex
SMask is set to $00FF hex
0 is set to 0
1 is set to 1
-1 is set to -1
Starting a Simulation
To start a simulation you must have an Assembled Microcode, and a successfully Assembled Macrocode program. If you have all of these you can then choose Run Simulator from the Machine menu. Each simulator will get it╒s own window and will start executing immediately. You may continue to work in the editor, or if you have set it up so that it takes input from the keyboard you could send input to the current simulation by clicking in it╒s window and typing.
What ever window is front most will receive keyboard input. Therefore if you have a text editor window forward, and a simulator window behind it, all of your keystrokes will go to the editor NOT the simulator. To direct keyboard input to a simulator window simply click in it to bring it to the front.
To stop a simulation simply close the window by clicking in the close box or choosing Close from the File menu. Closing the source code for a simulation will not stop the simulation. The only way to stop a simulation is to close it╒s window.
General I/O Scheme
General Input Scheme
To read input from a particular device works like this. You set InDev to the device id you would like to receive input from. You poll InputCntl . If InputCntl is zero then that means that there is no input pending. If InputCntl is one then that means there is some input waiting. You write a value of 2 into InputCntl, this tells the input device to place the data in InputCmnd & InputData. You poll InputCntl until it equals 3. InputCmnd & InputData will NOT be valid until InputCntl equals 3. After you have copied/used InputCmnd & InputData you store 4 into the InputCntl word letting the input device know that you╒ve ╥read╙ the buffer and are ready for any additional input.
For additional help see the input flow chart provided .
I/O Devices and their Commands
Input Devices
The predefined input device id╒s are listed below. These are the values that you would store into InDev to receive input from an input device.
Null Device = 0
Keyboard Device = 1
Another Simulator = 3
Any other device id will be reset by the Simulator to 0 (Null Device). For a list of input devices and their control word values .
Null Device
Null device has no commands and does nothing.
Keyboard Device
Keyboard Device receives input from the keyboard. The keyboard is ALWAYS reading the keyboard and storing the characters that are typed. Setting InDev to 1 simply tells the input hardware to check the keyboard buffer for input. The keyboard hardware stores up to 256 keystrokes. When the buffer gets full it deletes the oldest entry in the buffer.
You need not have InDev set to Keyboard Device to have the keyboard function. The keyboard will read and store keystrokes regardless of what device InDev is set to.
Another Simulator
You can accept input from another simulator. This is called Inter-Process-Communication or IPC. There is an IPC input device that is always running and accepting input from other simulators that are running. Much like the keyboard, the IPC processor stores up to 256 messages from other simulators. When it╒s buffer gets full it throws out the oldest message in the buffer. By setting InDev to Another Simulator it tells the input system to get it╒s input from the IPC buffer.
Like the keyboard the IPC input buffer accepts input from other simulators regardless of what value is in InDev.
Command #6 is used for a particular simulator to ╥set╙ it╒s own ID. This ID will be used by other simulator╒s in their OutDev location to write to another simulator. You have to actually set an id value > 2, otherwise you will never receive any input from another simulator. Each simulator╒s id value comes initialized as 0.
Contents of InputCmnd & InputData
InputCmnd & InputData will contain different information depending on what type of device is being used for input.
Keyboard Input
InputCmnd will contain a bit map of what modifier╒s where being held down when the key was typed. Modifiers are key╒s on the Macintosh keyboard like: Shift, Caps-lock, option, and the command-key. There is a bit in this word for each modifier. If that bit is set then that modifier key was held down when the keystroke was recorded.
Bit 11 set = Option key down
Bit 10 set = Caps Lock down
Bit 9 = Shift Key down
Bit 8 = Command key down
InputData will contain the ASCII value of the keystroke in the lower 8-bits of the word. The character that the ASCII value represents can be found on page 247 of Inside Macintosh Volume 1. For the most part the Macintosh character set is a standard ASCII set with some additions mapped onto values that ASCII doesn╒t use.
Another Simulator Input
InputCmnd will contain the device id of the simulator that sent the message.
InputData will contain the 16-bit value that the simulator sent to your IPC buffer. The meaning of this word is up to the programmer.
General Output Scheme
Output works similar to input. However for output you can assume the output device is always ready so there is no need to poll OutputCntl for a certain value. To accomplish output you store a command word into OutputCmnd and then store the desired data value into OutputData. After you have the command and it╒s associated data in OutputCmnd & OutputData you store a 1 into OutputCntl. The 1 is a signal to the output processor to grab the OutputCmnd & OutputData and act on it. The meaning of OutputCmnd is different depending on the type of output device.
Output Devices
The predefined output device id╒s are listed below. These are the values that you would store into OutDev to send output to an output device.
Null Device = 0
Screen Device = 2
Another Simulator = Any value > 2
Screen Device OutputCmnd values
0 Do nothing
1 Write Character: the Ascii value of OutputData is written to the screen at the current cursor location, if the value is too large only the lower 8 bits are used in determining the character value. The cursor location is updated by one column as a result of this operation. If the column is greater than 79 then the cursor is moved onto the next line. If the cursor row is greater than 23 then the whole screen is scrolled up a single line.
2 Move Cursor to Location: OutputData should contain the screen location to move the cursor to. The high byte is the row, and the low byte is the column, the screen is 80 columns by 24 rows, numbered from 0 to 79 & 0 to 23 respectively. if either one of the values is too big then they are mod'ed by 80 or 24 to obtain the screen location.
4 Get Cursor Location: OutputData will contain the cursor location after the command has completed executing. the high byte will contain the row, and the low byte will contain the column.
8 Get Character: after this command has completed OutputData will contain the character value of the character at the current cursor location. The screen is initialized to contain all spaces, therefore if you retrieve a character from a location that you haven╒t written to you will have a space returned.
16 Clear Screen: This operation clears the screen. It does NOT change the cursor location. The screen is initialized to contain all spaces.
32 Scroll Screen: OutputData should contain a value between -24 & 24, that is the number of lines to scroll the screen. Negative numbers scroll the screen up making room at the bottom. Positive numbers scroll the screen down making room at the top. The cursor location is NOT adjusted as a result of this command.
Another Simulator Device Command Word Values
When you send output to another simulator only the value in OutputData is transmitted. You current process id is also automatically transfers as part of the message to the destination simulator. The process id can be set by setting InDev to 3, storing the desired id in InputData and writing a value of 6 into InputCntl, for more information regarding this please and the section Titled ╥Another Simulator╙.
Sending output to another simulator works similar to the screen, but unlike the screen the OutputCntl word might contain a status value after the write has been accomplished. If you do a write and OutputCntl isn╒t reset to 0 then you just attempted a write to a nonexistent simulator. The value that indicates you last write failed is a 2, you can poll OutputCntl until it either becomes a 2 or a 0.
In addition to sending information to another simulator you can test to see if the destination simulator╒s buffer is full. To test the simulator╒s input buffer you write a value of 4 into OutputCntl, if the value of OutputCntl comes back as 5 then the destination machine╒s buffer is full and you should suspend output until it╒s empty. If OutputCntl is a 0 after checking the buffer then the destination machine╒s buffer has room for at least one more message.
Simulator Misc.
This section is here to cover topics that don╒t really fit in with the above categories. Nothing here is absolutely necessary to use MacSim. But it is provided for general information.
Constant Registers
It is not explicitly bad to attempt to load the CBus into one of the pre-defined constant registers of 0, -1, 1, AMask, and SMask. However the simulator will trap this attempt and not actually store the values. The constant register╒s can not be over written with the Microcode execution and therefore their values are guaranteed to be as documented. The AMask and SMask are initialized with a hex values of $0FFF and $00FF respectively and are useful for address masking.
Memory Requirements
Although it nice to think of all this in the abstract the Simulator is a piece of software and therefore consumes system RAM from the Macintosh. In addition to the window overhead, each simulator consumes about 20K of space while executing. While this is not a lot of memory it can add up if you have several simulators running and few text windows open in the background. If you are going to run several simulations please increase the amount of memory allocated to MacSim under Multi-finder.
Performance and Multiprocessing
The simulator is a software simulator and can be slow at time. The actual simulation code has been coded in assembly language for speed and we╒ve worked very hard to make the input/output code efficient. However each simulator is given a time slice of the Macintosh╒s processor in a round robin fashion, and after giving each simulator a number of clock cycles we have to service the Macintosh╒s OS with a rather lengthy call to GetNextEvent in order to respond to any potential user commands in the menu╒s or windows of the MacSim program. Although it is theoretically possible to open up any number of simulations that memory allows for, it╒s unreasonable to expect them to preform well under these conditions. We have found that the simulator isn╒t too bad on a Macintosh Plus, but if you can run it on some faster hardware you will be happier. We do not recommend running over three simulator╒s at once on a Macintosh Plus or SE, 4 or 5 seem to be just about the limit of human tolerance on a Macintosh SE/30.
The simulator does run noticeably faster on a Macintosh not running Multi-Finder. If it is at all possible, running MacSim under the Finder environment is faster and more desirable. MacSim will run under Multi-Finder, however if you switch out of MacSim into another application MacSim╒s execution is suspended to avoid taking undo processor time away from other Macintosh applications executing at the time.
Due to the actual implementation of the input/output system the simulator will run faster if you set InDev and OutDev to zero. We would recommend incurring the additional overhead of this operation if you were about to start executing a loop of assembly instructions that might take some time.
Memory Reads & Writes
The simulator follow╒s Tanenbaum╒s example exactly in reference to the # of clock cycles it takes to due a read or write to memory. You must keep rd or wr set for two consecutive Microcode instructions for the memory access to successfully complete. If the rd or wr are not set during both instructions the access will not happen and you will have wasted a Microcode instruction.
I/O and Clock Cycles
Input/Output is accomplished ╥between╙ microcode instructions. However there is no direct method of determining when the next I/O service will be accomplished. Since the checking of I/O is a very expensive operation, the simulator executes several Microcode instructions in a time-slice, and then does a single I/O operation. So to encode any I/O operations into the Microcode as a single Macrocode instruction would require the Microcode to poll the I/O memory addresses much like the Macrocode is required to do. Although we have not tried this it is doubtful any real speed increase in I/O would occur.
However when an I/O operation is done, it is atomic. No Microcode instructions are executed until the Macintosh has actually accomplished the entire I/O operation. At the end of the I/O operation all memory locations in the I/O address space are updated to reflect the status of the I/O operation in accordance with and . Read or Input operations are checked first, followed by Write or Output operations.
Sample Files
Along with MacSim we have provided a number of sample files. A general rule of thumb is that Microcode files end in .mc, and Macrocode files end in .asm. This is not required by MacSim, just convenient for the user. All of the .asm files contain comments explaining what they demonstrate. In addition to the .asm files we have provided a typed in copy of the Microcode provided in Tanenbaum╒s book. This file is called ╥Standard.mc╙. All of the sample .asm files use this file as their Microcode parent.
Disclaimer
Although the authors have taken reasonable measures to ensure MacSim╒s stability they can not be held liable for any damages that result from the use of MacSim. The authors do not make any claims as to the appropriateness of MacSim for any particular purpose.
Numerous trademarked and registered symbols are mentioned throughout this document. The authors and the California State University system recognize that these are trademarks of other individuals, institutions, and company╒s.
Andrew Tanenbaum was not consulted on this project and as of the writing of this document, to the best of the authors knowledge, knows nothing about MacSim and in no way endorses it╒s use with any of his literary works published to date.
The authors reserve all copyrights to MacSim, it╒s related source code, and documentation.
This document was produced using the FullWrite Professional Word Processing System on a 2 megabyte Macintosh SE/30. It was printed on an HP DeskWriter 300 dot-per-inch ink-jet printer. It uses the following Macintosh system fonts: Bookman, Avant Garde, Courier.
1st printing: Sunday, April 15, 1990
2nd printing: Sunday, April 15, 1990
MacSim version 1.1 by Steve LoBasso and David M. O╒Rourke.
Copyright 1990 by Steve LoBasso and David M. O╒Rourke.
---------- Sidebars ----------
MacSim 1.1
A MicroCode Simulator for the Macintosh Computer
by
David M. O╒Rourke and Steve LoBasso
The Four Parts of MacSim
Personalization Dialog
After you have clicked on the ╥Ok╙ button this information can NEVER be changed. It is used by MacSim and is printed on the top of each page when you print your text from the MacSim text editor.
If Page Setup and Print can not be selected that means there is no printer currently selected. Refer to the Macintosh owner╒s manual for information about selecting a printer from Chooser.
Status Panel
File Type Dialog
Any Microcode file can reassembled and saved at any time. But remember any Macrocode programs that use that Microcode as a parent must be consistent with what the Microcode implements. If you remove any instructions from the Microcode you must remember to also remove the instruction╒s Mnemonics from the Mnemonic table, and then change any Macrocode program that happens to use that Mnemonic.
#
lodd,0x4500-4,bx = 3,cx = 1;
retn,1024;
jsr,0xffff+,home = 0;
#
Sample mnemonic Table
The Macro-assembler DOES NOT check to see if the # of bits for the operand overwrites the actual value of the opcode. For example if you have an instruction 0xABC0-12, then the Macrocode assembler will encode any operand into the lower 12 bits of the instruction, thereby overwriting the ╘BC╒ part of the instruction.
pc
ac
sp
ir
tir
0
1
-1
amask
smask
a
b
c
d
e
f
mar
mbr
alu
wr
rd
goto
lshift
rshift
inv
band
if
z
n
The Mnemonic table and Microcode are read from the parent file each time you choose the Assemble command from the Machine menu. So if you change the parent Microcode and save the changes it will affect any open Macrocode windows that are using that file as a parent. The next time you try to assemble any Macrocode window that is currently using that parent file, the assembler will use the newly assembled information from the parent. In addition if you change the Microcode parent file, and it has error╒s, and then you save that file with the error╒s, the previous versions of the Microcode and Mnemonic table are deleted. Therefore, for a file to be a Microcode parent it must be a successfully compiled Microcode program.
org 34
label1 dw 9
dw 0
MacSim Memory Map
Input Flow Chart
Input Device Command Table
InDev Value InputCntl Meaning
0 None Nothing
1 read 0 No Input Waiting
read 1 Input Waiting
write 2 Load Input
read 3 Input Ready
write 4 Clear Last Input
write 5 Dump/Clear Input Buffer
3 read 0 No Input Waiting
read 1 Input Waiting
write 2 Load Input
read 3 Input Ready
write 4 Clear Last Input
write 5 Dump/Clear Input Buffer
write 6 Set my ID, the value
currently in the
InputData word is used
as the process ID
Output Device Command Table
OutDev Value OutputCntl Meaning
2 read 0 No Output
write 1 Send OutputCmnd &
OutputData to Screen
> 2 read 0 No Output
write 1 Send Out
read 2 No Such process
write 3 Clear OutputCntl
write 4 Check Buffer
read 5 Buffer Full
NOTE: just because a destination machine╒s buffer isn╒t full doesn╒t mean that another machine won╒t write to the buffer while you╒re getting ready to do your write. There is a potential race condition here for the ╥last buffer╙ space. Under no circumstance will your most recent write be lost, rather one of the older values in the input buffer will be discarded. The input buffer is 256 messages long, and for the buffer to be that full means that there must be quite a few unacknowledged messages in the buffer. To avoid this situation we suggest that you set up a mechanism where the receiver acknowledges receipt of a particular message before you transmit another one.